package www.bplead.com.mydemo.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.zj.btsdk.BluetoothService;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import www.bplead.com.mydemo.R;
import www.bplead.com.printer.service.PrinterService;

/**
 * Created by wangyangzi on 2016/10/15.
 */
public class PrinterDeviceActivity extends AppCompatActivity implements View.OnClickListener {
    public static final String TAG = "MyDeviceListActivity";
    // Return Intent extra
    public static String EXTRA_DEVICE_ADDRESS = "device_address";

    // Member fields
    BluetoothService mService = null;
    BluetoothDevice con_dev = null;
    AlertDialog.Builder builder;
    ProgressDialog dialog = null;
    ProgressDialog bondWindow = null;

    private Button scanDevice;
    private Button enableBtn;
    private Button removeBtn;
    private SimpleAdapter mPairedDevicesAdapter;
    private ArrayAdapter<String> mNewDevicesArrayAdapter;
    private int pairedDevicePos;
    private List<Map<String,Object>> mPairedDevices;
    //已选中的设备
    private Map<Integer,Boolean> checkedDevices = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.device_list);   //显示列表界面

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setTitle("蓝牙设备启用");

        scanDevice = (Button) this.findViewById(R.id.scan_bluetooth_device);
        enableBtn = (Button) this.findViewById(R.id.button_enable);
        removeBtn = (Button) this.findViewById(R.id.button_remove);
        scanDevice.setOnClickListener(this);
        enableBtn.setOnClickListener(this);
        removeBtn.setOnClickListener(this);
        //创建蓝牙服务
        mService = new BluetoothService(this, mHandler);
        //获得已配对设备
        mPairedDevices = getPairedDevices();
        // Initialize array adapters. One for already paired devices and
        // one for newly discovered devices
        //mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
        // Find and set up the ListView for paired devices
        mPairedDevicesAdapter = new SimpleAdapter(this,mPairedDevices,R.layout.device_item,new String[]{"bluetooth_device_name","bluetooth_device_address"},new int[]{R.id.bluetooth_device_name,R.id.bluetooth_device_address});
        ListView pairedListView = (ListView) findViewById(R.id.paired_bluetooth_devices);
        pairedListView.setAdapter(mPairedDevicesAdapter);
        pairedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                CheckBox cb = (CheckBox) view.findViewById(R.id.bluetooth_device_checkbox);
                if(cb.isChecked()){//取消选中
                    cb.setChecked(false);
                    checkedDevices.remove(position);
                }else{//选中
                    cb.setChecked(true);
                    checkedDevices.put(position,true);
                }
                updateButtonState();
            }
        });

        //其他可用设备
        // Find and set up the ListView for newly discovered devices
        mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
        ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
        newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
        newDevicesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // Cancel discovery because it's costly and we're about to connect
                mService.cancelDiscovery();
                pairedDevicePos = position;
                // Get the device MAC address, which is the last 17 chars in the View
                String info = ((TextView) view).getText().toString();
                final String address = info.substring(info.length() - 17);

                con_dev = mService.getDevByMac(address);

                try {
                    // 发起配对请求
                    if (con_dev.getBondState() == BluetoothDevice.BOND_NONE) {
                        Method creMethod = BluetoothDevice.class.getMethod("createBond");
                        Log.e("TAG", "开始配对");
                        creMethod.invoke(con_dev);
                    } else {
                    }
                } catch (Exception e) {
                    Toast.makeText(PrinterDeviceActivity.this,"无法配对",Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                }
                // mService.connect(con_dev);
            }
        });

        // Register for broadcasts when a device is discovered
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(mReceiver, filter);

        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, filter);

        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        this.registerReceiver(mReceiver, filter);
    }

    private void updateButtonState(){
        if(checkedDevices.size() == 1){
            enableBtn.setEnabled(true);
            removeBtn.setEnabled(true);
        }else if(checkedDevices.size() > 1){
            enableBtn.setEnabled(false);
        }else{
            enableBtn.setEnabled(false);
            removeBtn.setEnabled(false);
        }
    }
    private List<Map<String,Object>> getPairedDevices(){
        // Get a set of currently paired devices
        Set<BluetoothDevice> pairedDevices = mService.getPairedDev();

        mPairedDevices = new ArrayList<Map<String,Object>>();
        // If there are paired devices, add each one to the ArrayAdapter
        if (pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                HashMap<String,Object> map = new HashMap<>();
                map.put("bluetooth_device_name",device.getName());
                map.put("bluetooth_device_address",device.getAddress());
                mPairedDevices.add(map);
            }
        } else {
            // String noDevices = getResources().getText(R.string.none_paired).toString();
            //mPairedDevicesArrayAdapter.add(noDevices);
        }

        return mPairedDevices;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if(id == android.R.id.home) {
            onBackPressed();
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //getMenuInflater().inflate(R.menu.device_scan, menu);
        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mService != null) {
            mService.cancelDiscovery();
        }
        this.unregisterReceiver(mReceiver);
        Log.d("exit", "================ hhhh ================");
    }

    /**
     * Start device discover with the BluetoothAdapter
     */
    private void doDiscovery() {
        // If we're already discovering, stop it
        if (mService.isDiscovering()) {
            mService.cancelDiscovery();
        }
        // Request discover from BluetoothAdapter
        mService.startDiscovery();
    }

    /**
     * 取消配对
     */
    private void unpairDevice(BluetoothDevice device) {
        try {
            Method m = device.getClass().getMethod("removeBond", (Class[]) null);
            m.invoke(device, (Object[]) null);
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }

    //启用和移除
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            //查找蓝牙设备
            case R.id.scan_bluetooth_device:
                //检查是否开启蓝牙，如果未开启则提示开启
                BluetoothAdapter myAdapter = BluetoothAdapter.getDefaultAdapter();
                if(!myAdapter.isEnabled()){
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivity(intent);
                }
                //蓝牙已打开，那么开始搜索设备
                else{
                    doDiscovery();
                    dialog = new ProgressDialog(this);
                    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                    dialog.setCancelable(false);
                    dialog.setCanceledOnTouchOutside(false);
                    dialog.setTitle("设备查找");
                    dialog.setMessage("正在搜索附近的蓝牙设备...");
                    dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "停止查找",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    mService.cancelDiscovery();
                                    dialog.dismiss();
                                }
                            });
                    dialog.show();
                }
                break;
            case R.id.button_enable:
                //弹出确认框
                builder = new AlertDialog.Builder(PrinterDeviceActivity.this);
                builder.setMessage("确认启用选中设备吗?");
                builder.setTitle("提示");
                builder.setCancelable(false);
                builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //获取选中的设备，启用
                        Map<String,Object> pairedDevice = null;
                        for(Map.Entry<Integer,Boolean> entry : checkedDevices.entrySet()){
                            pairedDevice = mPairedDevices.get(entry.getKey());
                            break;
                        }
                        if(pairedDevice != null){
                            SharedPreferences preferences = getSharedPreferences("current_device", Activity.MODE_PRIVATE);
                            SharedPreferences.Editor editor = preferences.edit();
                            editor.putString("current_print_device", "bluetooth");
                            editor.putString("bluetooth_print_device_info", pairedDevice.get("bluetooth_device_address") + "#" + pairedDevice.get("bluetooth_device_name"));
                            editor.commit();
                            //启用成功，停止之前的蓝牙打印服务
                            PrinterService.stop();
                            finish();

                       }else{
                            Toast.makeText(PrinterDeviceActivity.this,"选中设备：" + checkedDevices.size() + "个",Toast.LENGTH_SHORT).show();
                        }
                        dialog.dismiss();
                    }
                });
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                builder.create().show();
                break;
            case R.id.button_remove:
                SharedPreferences preferences = getSharedPreferences("current_device", Activity.MODE_PRIVATE);
                SharedPreferences.Editor editor = preferences.edit();
                String deviceInfo = preferences.getString("bluetooth_print_device_info","error");
                String mac = "";
                if(!"error".equals(deviceInfo)){
                    mac = deviceInfo.substring(0, deviceInfo.indexOf("#"));
                }
                //获取选中的设备，解除绑定
                String[] deleteDevices = new String[checkedDevices.size()];
                int index = 0;
                for(Map.Entry<Integer,Boolean> entry : checkedDevices.entrySet()){
                    Map<String,Object> pairedDevice2 = mPairedDevices.get(entry.getKey());
                    String address =  pairedDevice2.get("bluetooth_device_address").toString();
                    BluetoothDevice bd = mService.getDevByMac(address);
                    unpairDevice(bd);
                    if(address.equals(mac)){
                        editor.remove("current_device");
                        editor.remove("bluetooth_print_device_info");
                        editor.commit();
                    }
                    deleteDevices[index++] = bd.getAddress();
                }
                //从列表中移除
                Iterator<Map<String,Object>> items = mPairedDevices.iterator();
                while (items.hasNext()){
                    Map<String,Object> m = items.next();
                    String delAddress = m.get("bluetooth_device_address").toString();
                    for(int i=0;i<deleteDevices.length;i++){
                        if(deleteDevices[i].equals(delAddress)){
                            items.remove();
                        }
                    }
                }
                //从checkbox中移除
                checkedDevices.clear();
                updateButtonState();
                //刷新ListView
                mPairedDevicesAdapter.notifyDataSetChanged();
                break;
        }
    }

    /**
     * 创建一个Handler实例，用于接收BluetoothService类返回回来的消息
     */
    public final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BluetoothService.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BluetoothService.STATE_CONNECTED:   //已连接
                            Log.d("蓝牙调试", "已连接！");
                            Toast.makeText(PrinterDeviceActivity.this,"已连接!",Toast.LENGTH_SHORT).show();
                            break;
                        case BluetoothService.STATE_CONNECTING:  //正在连接
                            Log.d("蓝牙调试","正在连接.....");
                            Toast.makeText(PrinterDeviceActivity.this,"正在连接.....",Toast.LENGTH_SHORT).show();
                            break;
                        case BluetoothService.STATE_LISTEN:     //监听连接的到来
                        case BluetoothService.STATE_NONE:
                            Log.d("蓝牙调试","等待连接.....");
                            break;
                    }
                    break;
                case BluetoothService.MESSAGE_CONNECTION_LOST:    //蓝牙已断开连接
                    Log.d("蓝牙调试","连接已断开.....");
                    Toast.makeText(PrinterDeviceActivity.this,"连接已断开.....",Toast.LENGTH_SHORT).show();
                    break;
                case BluetoothService.MESSAGE_UNABLE_CONNECT:     //无法连接设备
                    Log.d("蓝牙调试","无法连接设备.....");
                    Toast.makeText(PrinterDeviceActivity.this,"无法连接设备.....",Toast.LENGTH_SHORT).show();
                    break;
            }
        }

    };
    // The BroadcastReceiver that listens for discovered devices and
    // changes the title when discovery is finished
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // If it's already paired, skip it, because it's been listed already
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    String newDevice = device.getName() + "\n" + device.getAddress();
                    boolean flag = false;
                    for(int i=0;i<mNewDevicesArrayAdapter.getCount();i++){
                        if(newDevice.equals(mNewDevicesArrayAdapter.getItem(i).toString())){
                            flag = true;
                            break;
                        }
                    }
                    if(!flag){
                        mNewDevicesArrayAdapter.add(newDevice);
                    }
                }
                // When discovery is finished, change the Activity title
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                setProgressBarIndeterminateVisibility(false);
                setTitle(R.string.select_device);
                if (mNewDevicesArrayAdapter.getCount() == 0) {
                    String noDevices = getResources().getText(R.string.none_found).toString();
                    mNewDevicesArrayAdapter.add(noDevices);
                }
                if(dialog != null){
                    dialog.dismiss();
                }
            } else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                switch (device.getBondState()){
                    case BluetoothDevice.BOND_NONE:
                        if(bondWindow != null) {
                            bondWindow.dismiss();
                            bondWindow = null;
                            Toast.makeText(PrinterDeviceActivity.this,"配对失败",Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case BluetoothDevice.BOND_BONDING:
                        Log.d(TAG,"绑定状态改变，与设备" + device.getName() + "绑定中...");
                        bondWindow = new ProgressDialog(PrinterDeviceActivity.this);
                        bondWindow.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                        bondWindow.setCancelable(false);
                        bondWindow.setCanceledOnTouchOutside(false);
                        bondWindow.setTitle("设备配对");
                        bondWindow.setMessage("正在与设备" + device.getName() + "进行配对...");
                        bondWindow.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        bondWindow.dismiss();
                                        bondWindow = null;
                                    }
                                });
                        bondWindow.show();
                        break;
                    case BluetoothDevice.BOND_BONDED:
                        if(bondWindow != null) {
                            bondWindow.dismiss();
                            bondWindow = null;
                        }

                        //从可用设备中移除
                        mNewDevicesArrayAdapter.remove(mNewDevicesArrayAdapter.getItem(pairedDevicePos));
                        //在已配对设备中添加
                        HashMap<String,Object> map = new HashMap<>();
                        map.put("bluetooth_device_name",device.getName());
                        map.put("bluetooth_device_address",device.getAddress());
                        mPairedDevices.add(map);
                        //刷新listview
                        mPairedDevicesAdapter.notifyDataSetChanged();
                        Toast.makeText(PrinterDeviceActivity.this,"配对成功！",Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        }
    };
}
